﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Office.Interop.Excel;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;

namespace test_trace
{
    class Program
    {
        private static string drFileName = null;
        private static string testFileName = null;
        private static string[] derivedRequirements;
        private static Dictionary<string, List<string>> theTrace;

        static void Main(string[] args)
        {
            if (args.Length != 2)
            {
                Console.WriteLine("Usage: test-trace <requirements text file> <system test spreadsheet>");
                Console.WriteLine("Usage: test-trace -o <verbose|simple|normal(default)> -r <requirements text file> -t <system test spreadsheet>");
            }
            else
            {
                // One to many realtionship between requirement and test cases.
                theTrace = new Dictionary<string, List<string>>();

                drFileName   = args[0];
                testFileName = args[1];
 
                // Read the derived requirements list from the text file
                loadRequirements(drFileName);
                
                // Read the list of tests from the spreadsheet
                loadTests(derivedRequirements, testFileName);

                // Output the results
                displayTrace();
                //writeCSV();
                Console.ReadLine();
            }
        }

        private static void loadRequirements(string fileName)
        {
            try
            {
                derivedRequirements = System.IO.File.ReadAllLines(fileName);
            }
            catch (Exception fileIOExcpetion)
            {
                Console.WriteLine("Exception: {0}", fileIOExcpetion.ToString());
            }
        }

        private static void loadTests(string[] requirements, string fileName)
        {
            // Open Excel and get first worksheet.
            try
            {
                var application = new Application();
                var workbook = application.Workbooks.Open(fileName);
                var worksheet = workbook.Worksheets[6] as Microsoft.Office.Interop.Excel.Worksheet;

                Console.WriteLine("Gathering requirements to test case reationships...");
                uint count = 0;
                Console.Write("0%");

                foreach (string requirement in requirements)
                {
                    for (int reqCount = 11; reqCount < 550; reqCount++)
                    {
                        Microsoft.Office.Interop.Excel.Range testCaseRange = (Microsoft.Office.Interop.Excel.Range)worksheet.Cells[reqCount, 2];
                        Microsoft.Office.Interop.Excel.Range requirementRange = (Microsoft.Office.Interop.Excel.Range)worksheet.Cells[reqCount, 3];
                        string testCaseStr = Convert.ToString(testCaseRange.Value2);
                        string requirementID = Convert.ToString(requirementRange.Value2);

                        if (null != requirementID)
                        {
                            if (requirementID.Contains(requirement))
                            {
                                List<string> testCases;
                                try
                                {
                                    testCases = theTrace[requirement];

                                    // Append to an existing list
                                    string[] lines = Regex.Split(testCaseStr, "\r\n");

                                    foreach (string line in lines)
                                    {
                                        testCases.Add(line);
                                    }
                                }
                                catch (Exception)
                                {
                                    // Add a new list
                                    testCases = new List<string>();

                                    string[] lines = Regex.Split(testCaseStr, "\r\n");

                                    foreach (string line in lines)
                                    {
                                        testCases.Add(line);
                                    }

                                    theTrace.Add(requirement, testCases);
                                }
                            }
                        }
                    }

                    count++;

                    Console.Write("\r{0:0}%", (float)((float)(count)/(float)(requirements.Length))*100.0);
                }
                Console.WriteLine("");

                workbook.Close(0);
                application.Quit();
                
            }
            catch (Exception myException)
            {
                Console.WriteLine("Exception: {0}", myException.ToString());
            }
        }

        private static void displayTrace()
        {
            foreach (KeyValuePair<string, List<string>> entry in theTrace)
            {
                Console.Write("{0} :", entry.Key);
                foreach (string testCase in entry.Value)
                {
                    Console.Write(" " + testCase);
                }
                if (entry.Value.Count == 0)
                {
                    Console.WriteLine(" *");
                }
                else
                {
                    Console.WriteLine("");
                }
            }
        }

        private static void writeCSV()
        {
            foreach (KeyValuePair<string, List<string>> entry in theTrace)
            {
                Console.Write(entry.Key);
                Console.Write("," + entry.Value.Count);
                foreach (string testCase in entry.Value)
                {
                    Console.Write("," + testCase);
                }
                Console.WriteLine("");
            }
        }

    }
}
